traffic_light_fsm
Source: HW6/traffic_light_fsm.sv (modified 2025-11-09 23:50)
// traffic_light_fsm.sv
`timescale 1ns/1ps
module TrafficLightFSM #(
// 时钟与“秒拍”设置
parameter int unsigned CLK_HZ = 50_000_000,
parameter int unsigned TICK_HZ = 1, // 1Hz = 每秒一次 tick
// 各相位持续“秒数”(Moore)
parameter int unsigned T_A_GREEN = 4,
parameter int unsigned T_A_YEL = 2,
parameter int unsigned T_B_GREEN = 4,
parameter int unsigned T_B_YEL = 2,
parameter int unsigned T_ALL_RED = 5 // 关键:双红 5 秒
)(
input logic clk,
input logic rst_n,
// 便于上色的独立 RGB 端口
output logic LA_R, LA_Y, LA_G,
output logic LB_R, LB_Y, LB_G,
// 兼容作业图的 3 位总线(约定 [2]=R, [1]=Y, [0]=G)
output logic [2:0] LA,
output logic [2:0] LB
);
// =========================
// 1) 1Hz tick 分频器
// =========================
localparam int unsigned DIVISOR = (TICK_HZ == 0) ? 1 : (CLK_HZ / TICK_HZ);
logic [$clog2(DIVISOR)-1:0] div_cnt;
logic tick_1hz;
always_ff @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
div_cnt <= '0;
tick_1hz <= 1'b0;
end else begin
if (div_cnt == DIVISOR-1) begin
div_cnt <= '0;
tick_1hz <= 1'b1;
end else begin
div_cnt <= div_cnt + 1'b1;
tick_1hz <= 1'b0;
end
end
end
// =========================
// 2) 状态机(Moore)
// =========================
typedef enum logic [2:0] {
S_A_G, // A 绿
S_A_Y, // A 黄
S_ALL_RED1, // 双红(A->B 过渡)
S_B_G, // B 绿
S_B_Y, // B 黄
S_ALL_RED2 // 双红(B->A 过渡)
} state_t;
state_t state, state_n;
// =========================
// 3) 当前状态计秒
// =========================
// 计算最长持续时间以决定计数器位宽
localparam int unsigned MAX_AB1 = (T_A_GREEN > T_A_YEL) ? T_A_GREEN : T_A_YEL;
localparam int unsigned MAX_AB2 = (T_B_GREEN > T_B_YEL) ? T_B_GREEN : T_B_YEL;
localparam int unsigned MAX_AB3 = (MAX_AB1 > MAX_AB2) ? MAX_AB1 : MAX_AB2;
localparam int unsigned MAX_DUR = (MAX_AB3 > T_ALL_RED) ? MAX_AB3 : T_ALL_RED;
localparam int unsigned SECW = (MAX_DUR <= 1) ? 1 : $clog2(MAX_DUR);
logic [SECW-1:0] sec_cnt;
logic sec_done;
function automatic int unsigned dur_of(state_t s);
case (s)
S_A_G : return T_A_GREEN;
S_A_Y : return T_A_YEL;
S_ALL_RED1 : return T_ALL_RED;
S_B_G : return T_B_GREEN;
S_B_Y : return T_B_YEL;
S_ALL_RED2 : return T_ALL_RED;
default : return T_ALL_RED;
endcase
endfunction
always_ff @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
sec_cnt <= '0;
end else if (tick_1hz) begin
if (sec_cnt == dur_of(state)-1)
sec_cnt <= '0;
else
sec_cnt <= sec_cnt + 1'b1;
end
end
assign sec_done = tick_1hz && (sec_cnt == dur_of(state)-1);
// 次态组合逻辑
always_comb begin
state_n = state;
unique case (state)
S_A_G : if (sec_done) state_n = S_A_Y;
S_A_Y : if (sec_done) state_n = S_ALL_RED1;
S_ALL_RED1 : if (sec_done) state_n = S_B_G;
S_B_G : if (sec_done) state_n = S_B_Y;
S_B_Y : if (sec_done) state_n = S_ALL_RED2;
S_ALL_RED2 : if (sec_done) state_n = S_A_G;
default : state_n = S_A_G;
endcase
end
// 状态寄存器
always_ff @(posedge clk or negedge rst_n) begin
if (!rst_n) state <= S_A_G;
else state <= state_n;
end
// =========================
// 4) Moore 输出(仅依赖状态)
// =========================
always_comb begin
LA_R=0; LA_Y=0; LA_G=0;
LB_R=0; LB_Y=0; LB_G=0;
unique case (state)
S_A_G : begin LA_G=1; LB_R=1; end
S_A_Y : begin LA_Y=1; LB_R=1; end
S_ALL_RED1 : begin LA_R=1; LB_R=1; end
S_B_G : begin LA_R=1; LB_G=1; end
S_B_Y : begin LA_R=1; LB_Y=1; end
S_ALL_RED2 : begin LA_R=1; LB_R=1; end
endcase
end
// 汇总 3 位总线([2]=R, [1]=Y, [0]=G)
assign LA = {LA_R, LA_Y, LA_G};
assign LB = {LB_R, LB_Y, LB_G};
// (可选)安全断言:在 ALL_RED 状态时两灯必须红
// property p_allred; @(posedge clk) (state inside {S_ALL_RED1,S_ALL_RED2}) |-> (LA_R && LB_R && !LA_Y && !LA_G && !LB_Y && !LB_G); endproperty
// assert property (p_allred);
// 把内部信号对外可见(便于 .do 抓)
// synthesis translate_off
// (* keep = "true" *) // 某些综合器的保留指示;仿真无影响
// synthesis translate_on
endmodule